﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using log4net;
using RollBackLib.src.utils;
using System.IO;

namespace RollBack.src.ui
{
    /// <summary>
    /// Any application specific User Interface information like
    /// the title of every dialog box or version number etc.
    /// </summary>
    public class AppUI
    {
        public static string m_DialogTitle = "RollBack";
        private static readonly ILog log = LogManager.GetLogger(typeof(AppUI));
        public static BackupAppForm m_MainApp
        {
            get;
            set;
        }
        private static ExceptionMessageForm m_exceptionMessage = new ExceptionMessageForm();

        public static string StatusMessage
        {
            get { string s = m_MainApp != null ? m_MainApp.getStatusMessage() : ""; return s; }
            set { if(m_MainApp!=null) { m_MainApp.setStatusText(value); } }
        }

        /// <summary>
        /// Display a message box with appropriate application title
        /// </summary>
        /// <param name="p"></param>
        internal static DialogResult ShowMessage(string p)
        {
            return MessageBox.Show(m_MainApp, p, m_DialogTitle);
        }

        internal static DialogResult ShowErrorMessage(string p)
        {
            return MessageBox.Show(m_MainApp, p, m_DialogTitle,MessageBoxButtons.OK,MessageBoxIcon.Error);
        }

        internal static DialogResult ShowMessage(string p, MessageBoxButtons messageBoxButtons)
        {
            return MessageBox.Show(m_MainApp, p, m_DialogTitle, messageBoxButtons);
        }

        internal static DialogResult ShowMessage(string p, MessageBoxButtons messageBoxButtons,MessageBoxIcon icon)
        {
            return MessageBox.Show(m_MainApp,p, m_DialogTitle, messageBoxButtons, icon);
        }

        internal static DialogResult ShowException(string s, Exception e)
        {
            m_exceptionMessage.m_messageTextBox.Text = s;
            string exstr = "\r\n" + e.Message + "\r\n\r\n";
            if (e.InnerException != null)
            {
                exstr += e.InnerException;
                exstr += "\r\n--- End of inner exception--\r\n";
            }
            exstr += e.StackTrace;
            m_exceptionMessage.m_stackTraceTextBox.Text = exstr;
            DialogResult result = m_MainApp != null ? m_exceptionMessage.ShowDialog(m_MainApp) : m_exceptionMessage.ShowDialog();
            return result;
        }

        /// <summary>
        /// Show the exception if the 'showDialog' flag is true.
        /// The flag is internally changed by the 'do not show future errors' checkbox.
        /// </summary>
        /// <param name="s"></param>
        /// <param name="e"></param>
        /// <param name="showDialog"></param>
        /// <returns></returns>
        internal static DialogResult ShowException(string s, Exception e,ref bool showDialog)
        {
            DialogResult result = DialogResult.OK;
            if (showDialog)
            {
                result = ShowException(s, e);
                if (m_exceptionMessage.m_doNotShowFutureErrors.Checked)
                {
                    showDialog = false;
                }
            }
            return result;
        }

        public static void showStatusMessage(string s)
        {
            if (m_MainApp != null)
            {
                m_MainApp.setStatusText(s);
            }
        }

        public static string AssemblyVersion
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString();
            }
        }

        internal static void LogAndShowException(string p, Exception e)
        {
            log.Error(p, e);
            ShowException(p, e);
        }

        /// <summary>
        /// Get the full path to the 'all.xml' file
        /// </summary>
        /// <returns></returns>
        internal static string getSettingsFile()
        {
            String path = getAppDataPath();
            String file = AppUtils.getSettingsFile(path);
            return file;
        }

        /// <summary>
        /// Get the full directory path where the application data is stored.
        /// Create it if it does not exist
        /// </summary>
        /// <returns></returns>
        internal static string getAppDataPath()
        {
            String path = "";
            try
            {
                path = System.IO.Directory.GetParent(Application.UserAppDataPath).FullName;
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }
            catch (Exception e)
            {
                String msg = "Error creating/getting AppDataPath <" + path + ">";
                log.Warn(msg,e);
                AppUI.LogAndShowException(msg, e);
            }

            return path;
        }

        internal static string getAppDBPath()
        {
            return getAppDataPath();
        }

        /// <summary>
        /// Relocate the applications files to break away from paths with application version number
        /// </summary>
        internal static void relocateAppFiles()
        {
            try
            {
                String srcPath = System.IO.Directory.GetParent(Application.LocalUserAppDataPath).FullName + "\\0.5.0.0";
                DirectoryInfo srcDir = new DirectoryInfo(srcPath);
                if (srcDir.Exists)
                {
                    FileSystemInfo[] files = srcDir.GetFileSystemInfos("*.xml");
                    String targetDir = System.IO.Directory.GetParent(Application.UserAppDataPath).FullName;
                    if (files != null && files.Length > 0)
                    {
                        foreach (FileSystemInfo f in files)
                        {
                            String targetPath = targetDir + "\\" + f.Name;
                            if (!File.Exists(targetPath))
                            {
                                try
                                {
                                    File.Move(f.FullName, targetPath);
                                    log.Info("Moving file <" + f + "> to <" + targetPath + ">");
                                }
                                catch (Exception e)
                                {
                                    log.Warn("Error moving <" + f.FullName + "> to <" + targetPath + ">", e);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.Warn("Error relocating files", e);
            }
        }
    }
}
